package cn.bfay.lion.rest.service.impl;

import com.google.common.base.Joiner;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import cn.bfay.lion.rest.client.rsp.ProductInfoRsp;
import cn.bfay.lion.rest.entity.UserProduct;
import cn.bfay.lion.rest.enums.WatchStatus;
import cn.bfay.lion.rest.error.RestBusinessError;
import cn.bfay.lion.rest.manager.JingdongManager;
import cn.bfay.lion.rest.mapper.UserProductMapper;
import cn.bfay.lion.rest.model.UserSession;
import cn.bfay.lion.rest.param.SetNoticePriceParam;
import cn.bfay.lion.rest.param.WatchOrUnwatchProductParam;
import cn.bfay.lion.rest.service.UserProductService;
import cn.bfay.lion.rest.vo.CheckWatchVo;
import cn.bfay.lion.rest.vo.UserProductVo;
import cn.bfay.web.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * UserProductServiceImpl.
 *
 * @author wangjiannan
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserProductServiceImpl extends AbstractService implements UserProductService {
    private final UserProductMapper userProductMapper;
    private final JingdongManager jingdongManager;

    @Override
    public void watchOrUnwatchProduct(WatchOrUnwatchProductParam watchOrUnwatchProductParam) {
        String openid = getUserSession().getOpenid();
        if (WatchStatus.UNWATCH.equals(watchOrUnwatchProductParam.getWatchStatus())) {
            watchProduct(openid, watchOrUnwatchProductParam.getSkuid());
        } else if (WatchStatus.WATCH.equals(watchOrUnwatchProductParam.getWatchStatus())) {
            unwatchProduct(openid, watchOrUnwatchProductParam.getSkuid());
        } else {
            log.warn("------watch-or-unwatch-product-------");
        }
    }

    private void unwatchProduct(String openid, String skuid) {
        UserProduct userProduct = new UserProduct();
        userProduct.setMark((byte) 0);
        userProduct.setNoticePrice(0.00);
        userProductMapper.update(userProduct, new QueryWrapper<UserProduct>().lambda()
            .eq(UserProduct::getOpenid, openid)
            .eq(UserProduct::getSkuid, skuid));
    }

    @Override
    public List<UserProductVo> getUserProducts() {
        String openid = getUserSession().getOpenid();
        List<UserProduct> userProducts = userProductMapper.selectList(new QueryWrapper<UserProduct>().lambda()
            .eq(UserProduct::getOpenid, openid)
            .eq(UserProduct::getMark, (byte) 1)
            .orderByDesc(UserProduct::getUpdateTime));
        if (CollectionUtils.isEmpty(userProducts)) {
            return null;
        }

        String skuids =
            Joiner.on(",").join(userProducts.stream().map(UserProduct::getSkuid).collect(Collectors.toList()));
        List<ProductInfoRsp> productInfoRsps = jingdongManager.getProductInfoBySkuids(skuids);

        List<ProductInfoRsp> productInfoRspsNew = new ArrayList<>();
        for (UserProduct userProduct : userProducts) {
            for (ProductInfoRsp productInfoRsp : productInfoRsps) {
                if (userProduct.getSkuid().equals(productInfoRsp.getSkuid())) {
                    productInfoRspsNew.add(productInfoRsp);
                    break;
                }
            }
        }
        List<UserProductVo> userProductVos = new ArrayList<>(productInfoRsps.size());
        productInfoRspsNew.forEach(productInfoRsp -> {
            UserProductVo userProductVo = new UserProductVo();
            BeanUtils.copyProperties(productInfoRsp, userProductVo);
            userProductVos.add(userProductVo);
        });
        return userProductVos;
    }

    @Override
    public void setNoticePrice(SetNoticePriceParam setNoticePriceParam) {
        String openid = getUserSession().getOpenid();
        String skuid = setNoticePriceParam.getSkuid();

        UserProduct oldUserProduct = userProductMapper.selectOne(new QueryWrapper<UserProduct>().lambda()
            .eq(UserProduct::getOpenid, openid)
            .eq(UserProduct::getSkuid, skuid));
        if (oldUserProduct == null || oldUserProduct.getMark() == 0) {
            throw new BizException(RestBusinessError.NEED_FOCUSED_ON);
        }

        UserProduct userProduct = new UserProduct();
        userProduct.setId(oldUserProduct.getId());
        userProduct.setNoticePrice((double) setNoticePriceParam.getNoticePrice());
        userProductMapper.updateById(userProduct);
    }

    @Override
    public CheckWatchVo checkWatch(String skuid) {
        CheckWatchVo checkWatchVo = new CheckWatchVo();
        checkWatchVo.setWatch(false);
        UserSession userSession = getUserSession();
        if (userSession == null) {
            return checkWatchVo;
        }

        String openid = getUserSession().getOpenid();
        UserProduct userProduct = userProductMapper.selectOne(new QueryWrapper<UserProduct>().lambda()
            .eq(UserProduct::getOpenid, openid)
            .eq(UserProduct::getSkuid, skuid));
        if (userProduct == null || userProduct.getMark() == 0) {
            return checkWatchVo;
        }
        checkWatchVo.setWatch(true);
        checkWatchVo.setNoticePrice(userProduct.getNoticePrice());
        return checkWatchVo;
    }
}
